(function (angular) {
    'use strict';
    var keydownModule = angular.module('fs.keydown', ['fs.storage']);
    keydownModule.factory('keydownService', keydownService);
    keydownService.$inject = ['$filter', 'storageService'];
    function keydownService($filter, storageService) {
        //=================================================
        //      On key down                             ===
        //=================================================
        //the formatManager should get from back.
        var formatInfo = storageService.getFormatInfo() || {};
        var decimalSeparator = formatInfo.decimalSeparator || '.';
        var FORMAT_MANAGER = {
            decimalSeparator: decimalSeparator
        };

        /**
         * Coder can type back space, delete, home and end etc.
         * @return boolean. when key which is being pressed is one of the following keys, return true.
         */
        function baseKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            if (evt.ctrlKey) {
                return (keyCode == 67     // ^C
                    || keyCode == 86     // ^V
                    || keyCode == 88);   // ^X
            } else {
                return (keyCode == 8     // back space
                    || keyCode == 46    // delete
                    || keyCode == 35    // home
                    || keyCode == 36    // end
                    || keyCode == 37    // <-
                    || keyCode == 38    // cursor up
                    || keyCode == 39    // ->
                    || keyCode == 40    // cursor down
                    || keyCode == 9);   // tab

            }
        }

        /**
         * Coder can enter.
         * @return boolean. when key which pressed is enter, return true.
         */
        function enterKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            return (keyCode == 13);     // enter
        }

        /**
         * type dot.
         * @return boolean. when key which pressed is dot, return true.
         */
        function dotKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            return (keyCode == 110                                 // '.'
                || (!evt.shiftKey && keyCode == 190));  // '.' on standard 102 keyboard   
        }

        /**
         * type decimal separator 
         * @return boolean. when key which pressed is decimal separator, return true.
         */
        function decimalSeparatorKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var mark;
            if (evt.shiftKey) {
                var shiftKey = {
                    '188': "<", '190': ">", '191': "?",
                    '48': ")", '49': "!", '50': "@",
                    '51': "#", '52': "$", '53': "%",
                    '54': "^", '55': "&", '56': "*",
                    '57': "(", '189': "_", '187': "+",
                    '192': "~", '219': "{", '221': "}",
                    '186': ":", '222': "\"", '173': "_"
                }
                mark = shiftKey[keyCode];
            } else {
                var normalKey = {
                    '188': ",", '110': FORMAT_MANAGER.decimalSeparator, '190': ".",//110 is in number keybord
                    '32': " ", '189': "-", '187': "=",
                    '49': "`", '219': "[", '221': "]",
                    '186': ";", '222': "'", '173': "_"
                }
                mark = normalKey[keyCode];
            }
            if (keyCode == 110) {
                (evt.srcElement || evt.target).value = (evt.srcElement || evt.target).value + FORMAT_MANAGER.decimalSeparator;
                evt.returnValue = false;
                if (evt.preventDefault) {
                    evt.preventDefault();
                }
            }
            return (FORMAT_MANAGER.decimalSeparator == mark);
        }

        /**
         * type letters.
         * @param 
         * @return boolean
         */
        function letterKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            return (keyCode >= 65 && keyCode <= 96);    // a - z;A - Z
        }

        /**
         * type number.
         * @return boolean
         */
        function numKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            return (!evt.shiftKey && keyCode >= 48 && keyCode <= 57)  // 0 - 9
                || (keyCode >= 96 && keyCode <= 105);   // 0 - 9 on standard 102 Keyboard 
        }

        /**
         * type ID includes letters, numbers, dash and underscore.
         * 0 - 9; a - z; A - Z; -; _;
         * 
         * @param 
         * @return boolean
         */
        function idKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            isValidKey = (letterKeyDown(e)) || (numKeyDown(e));    // 0 - 9; a - z; A - Z
            if (isValidKey) {
                return isValidKey;
            }
            return (keyCode == 109     // '-' on standard 102 keyboard
                || keyCode == 173	     // '-' or '_' in firefox broswer
                || keyCode == 189);    // '-' or '_' in other broswer
        }

        /**
         * type ID includes numbers, letters and underscore.
         * 0 - 9; a - z; A - Z; _;
         * 
         * @param 
         * @return boolean
         */
        function id2KeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            isValidKey = (letterKeyDown(e)) || (numKeyDown(e));    // 0 - 9; a - z; A - Z
            if (isValidKey) {
                return isValidKey;
            }
            return (evt.shiftKey && keyCode == 173		 // '_' in firefox broswer
                || evt.shiftKey && keyCode == 189);     // '_' in other broswer
        }

        /**
         * type ID includes numbers, letters and dash.
         * 0 - 9; a - z; A - Z; ,; -;
         * 
         * @param 
         * @return boolean
         */
        function id3KeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            isValidKey = (letterKeyDown(e)) || (numKeyDown(e));    // 0 - 9; a - z; A - Z
            if (isValidKey) {
                return isValidKey;
            }
            return (keyCode == 109     // '-' on standard 102 keyboard
                || (!evt.shiftKey && keyCode == 173)   // only '-' in firefox broswer
                || (!evt.shiftKey && keyCode == 189)   // only '-' in other broswer
                || keyCode == 188);  // ','
        }

        /**
         * type ID includes numbers, letters, dash, underscore, dot andt at.
         * 0 - 9; a - z; A - Z; -; _; .; @;
         * 
         * @param 
         * @return boolean
         */
        function id4KeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            isValidKey = (idKeyDown(e)) || (dotKeyDown(e));    // 0 - 9; a - z; A - Z; -; _; .;
            if (isValidKey) {
                return isValidKey;
            }
            return (evt.shiftKey && keyCode == 50);    // only '-' 
        }

        /**
         * type ID includes numbers and letters.
         * 0 - 9; a - z; A - Z;
         * 
         * @param 
         * @return boolean
         */
        function id5KeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            return (letterKeyDown(e)) || (numKeyDown(e));    // 0 - 9; a - z; A - Z
        }

        /**
         * type ID includes numbers, letters, dash, underscore and space.
         * 0 - 9; a - z; A - Z; -; _; ' ';
         * 
         * @param 
         * @return boolean
         */
        function id6KeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            return ((keyCode == 32) || idKeyDown(e));    // 0 - 9; a - z; A - Z; -; _; ' ';
        }

        /**
         * type class includes letters and dot.
         * a - z; A - Z; .;
         * 
         * @param 
         * @return boolean
         */
        function classpathKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            return (letterKeyDown(e) || dotKeyDown(e));    // a - z; A - Z; .;
        }

        /**
         * type float number.
         * @param value
         * @return
         */
        function floatKeyDown(e, value) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            var isValidKey = baseKeyDown(e);
            if (isValidKey) {
                return isValidKey;
            }
            isValidKey = numKeyDown(evt); // for number
            if (value && value.indexOf(FORMAT_MANAGER.decimalSeparator) != -1) {
                //if value is float
                return isValidKey;
            } else {
                //if value is integer, U can type decimal separator.
                return (isValidKey || (decimalSeparatorKeyDown(evt)));
            }
        }
        function minusKeyDown(e) {
            var evt = window.event || e;
            var keyCode = evt.which ? evt.which : evt.keyCode;
            return (keyCode == 109     // '-' on standard 102 keyboard
                || (!evt.shiftKey && keyCode == 173)   // only '-' in firefox broswer
                || (!evt.shiftKey && keyCode == 189)); // '-' or '_' in other broswer	
        }
        return {
            numKeyDown: numKeyDown,
            idKeyDown: idKeyDown,
            id2KeyDown: id2KeyDown,
            id3KeyDown: id3KeyDown,
            id4KeyDown: id4KeyDown,
            id5KeyDown: id5KeyDown,
            id6KeyDown: id6KeyDown,
            classpathKeyDown: classpathKeyDown,
            floatKeyDown: floatKeyDown,
            minusKeyDown: minusKeyDown
        };
    }
})(angular);